﻿using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Reflection;
using Zhp.Common.Extention;

namespace Zhp.Common.Swagger
{
    public static class SwaggerExtensions
    {
        public static IServiceCollection AddSwagger<T, K>(this IServiceCollection services)
        {
            services.AddEndpointsApiExplorer();
            services.AddSwaggerGen((c) =>
            {
                var apiEnumType = typeof(T);
                var apiGroupType = typeof(K);
                var fields = apiEnumType.GetEnumFields();
                foreach (var item in fields)
                {
                    var attr = item.GetCustomAttribute<ApiGroupEnumAttribute>();
                    c.SwaggerDoc(item.Name, new OpenApiInfo { Title = attr?.ApiGroupName, Version = attr?.Version });
                }

                c.DocInclusionPredicate((name, apiDesc) =>
                {
                    //返回true则在name分组中，返回false则不在name分组中
                    var apiGroup = apiDesc.CustomAttributes().FirstOrDefault(x => x.GetType().Name == apiGroupType.Name);

                    if (apiGroup != null)
                    {
                        var descNameInfo = apiGroup.GetType().GetProperties().FirstOrDefault(x => x.PropertyType.Name == apiEnumType.Name);
                        if (descNameInfo != null)
                        {
                            var descName = descNameInfo.GetValue(apiGroup);
                            if (descName?.ToString() == name)
                            {
                                return true;
                            }
                        }
                    }
                    else if (name == fields.FirstOrDefault(x => x.GetCustomAttribute<ApiGroupEnumAttribute>().IsDefault)?.Name)
                    {
                        //设置默认分组
                        return true;
                    }

                    return false;
                });

                //添加token
                c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
                {
                    Description = "JWT Authorization header using the Bearer scheme.",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.Http,
                    Scheme = JwtBearerDefaults.AuthenticationScheme.ToLower(),
                    BearerFormat = "JWT"
                });

                //验证token走授权逻辑
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    {
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference
                            {
                                Type = ReferenceType.SecurityScheme,
                                Id = JwtBearerDefaults.AuthenticationScheme
                            }
                        },
                        new string[] { }
                    }
                });
            });

            return services;
        }

        public static void UseSwagger<T>(this IApplicationBuilder app)
        {
            app.UseSwagger();
            app.UseSwaggerUI((c) =>
            {
                var fields = typeof(T).GetEnumFields();
                foreach (var item in fields)
                {
                    var attr = item.GetCustomAttribute<ApiGroupEnumAttribute>();
                    c.SwaggerEndpoint($"/swagger/{item.Name}/swagger.json", attr?.ApiGroupName);
                }
            });
        }
    }
}
